package com.minicoral.game2048;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;

public class GameView extends GridLayout
{

	public GameView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);

		initGameView();
	}

	public GameView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		initGameView();
	}

	public GameView(Context context)
	{
		super(context);
		initGameView();
	}

	private void initGameView()
	{
		setBackgroundColor(0xffbbada0);
		setColumnCount(4);
		setOnTouchListener(new OnTouchListener()
		{
			private float startX, startY, offsetX, offsetY;

			@Override
			public boolean onTouch(View v, MotionEvent event)
			{
				switch (event.getAction())
				{
				case MotionEvent.ACTION_DOWN:
					startX = event.getX();
					startY = event.getY();
					break;
				case MotionEvent.ACTION_UP:
					offsetX = event.getX() - startX;
					offsetY = event.getY() - startY;

					if (Math.abs(offsetX) > Math.abs(offsetY))
					{
						if (offsetX < -5)
						{
							swipeLeft();
						}
						if (offsetX > 5)
						{
							swipeRight();
						}
					}
					else
					{
						if (offsetY < -5)
						{
							swipeUp();
						}
						if (offsetY > 5)
						{
							swipeDown();
						}
					}
					break;

				}
				return true;
			}
		});
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{

		super.onSizeChanged(w, h, oldw, oldh);
		int cardWidth = (Math.min(w, h) - 20) / 4;
		addCard(cardWidth, cardWidth);
		startGame();
	}

	private Card[][] cardsMap = new Card[4][4];

	private void addCard(int cadtWidth, int cardHeight)
	{
		Card c;
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 4; j++)
			{
				c = new Card(getContext());
				c.setNum(0);
				addView(c, cadtWidth, cardHeight);
				cardsMap[i][j] = c;
			}
		}
	}

	private List<Point> emptyPoints = new ArrayList<Point>();

	private void addRandomNum()
	{
		emptyPoints.clear();
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 4; j++)
			{
				if (cardsMap[i][j].getNum() <= 0)
				{
					emptyPoints.add(new Point(i, j));
				}
			}
		}
		Point p = emptyPoints
				.remove((int) (Math.random() * emptyPoints.size()));
		cardsMap[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4);
	}

	private void startGame()
	{
		MainActivity.getMainActivity().clearScore();
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 4; j++)
			{
				cardsMap[i][j].setNum(0);
			}
		}
		addRandomNum();
		addRandomNum();
	}

	private void swipeLeft()
	{
		boolean flag = false;
		for (int x = 0; x < 4; x++)
		{
			for (int y = 0; y < 4; y++)
			{
				for (int y1 = y + 1; y1 < 4; y1++)
				{
					if (cardsMap[x][y1].getNum() > 0)
					{
						if (cardsMap[x][y].getNum() <= 0)
						{
							cardsMap[x][y].setNum(cardsMap[x][y1].getNum());
							cardsMap[x][y1].setNum(0);

							y--;
							flag = true;
						}
						else if (cardsMap[x][y].equals(cardsMap[x][y1]))
						{
							cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
							cardsMap[x][y1].setNum(0);
							MainActivity.getMainActivity().addScore(
									cardsMap[x][y].getNum());
							flag = true;
						}
						break;
					}
				}
			}
		}
		if (flag)
		{
			addRandomNum();
			checkComplete();
		}
	}

	private void swipeRight()
	{
		boolean flag = false;
		for (int x = 0; x < 4; x++)
		{
			for (int y = 3; y >= 0; y--)
			{
				for (int y1 = y - 1; y1 >= 0; y1--)
				{
					if (cardsMap[x][y1].getNum() > 0)
					{
						if (cardsMap[x][y].getNum() <= 0)
						{
							cardsMap[x][y].setNum(cardsMap[x][y1].getNum());
							cardsMap[x][y1].setNum(0);

							y++;
							flag = true;
						}
						else if (cardsMap[x][y].equals(cardsMap[x][y1]))
						{
							cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
							cardsMap[x][y1].setNum(0);
							MainActivity.getMainActivity().addScore(
									cardsMap[x][y].getNum());
							flag = true;
						}
						break;
					}
				}
			}
		}
		if (flag)
		{
			addRandomNum();
			checkComplete();
		}
	}

	private void swipeUp()
	{
		boolean flag = false;
		for (int y = 0; y < 4; y++)
		{
			for (int x = 0; x < 4; x++)
			{
				for (int x1 = x + 1; x1 < 4; x1++)
				{
					if (cardsMap[x1][y].getNum() > 0)
					{
						if (cardsMap[x][y].getNum() <= 0)
						{
							cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
							cardsMap[x1][y].setNum(0);

							x--;
							flag = true;
						}
						else if (cardsMap[x][y].equals(cardsMap[x1][y]))
						{
							cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
							cardsMap[x1][y].setNum(0);
							MainActivity.getMainActivity().addScore(
									cardsMap[x][y].getNum());
							flag = true;
						}
						break;
					}
				}
			}
		}
		if (flag)
		{
			addRandomNum();
			checkComplete();
		}
	}

	private void swipeDown()
	{
		boolean flag = false;
		for (int y = 0; y < 4; y++)
		{
			for (int x = 3; x >= 0; x--)
			{
				for (int x1 = x - 1; x1 >= 0; x1--)
				{
					if (cardsMap[x1][y].getNum() > 0)
					{
						if (cardsMap[x][y].getNum() <= 0)
						{
							cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
							cardsMap[x1][y].setNum(0);

							x++;
							flag = true;
						}
						else if (cardsMap[x][y].equals(cardsMap[x1][y]))
						{
							cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
							cardsMap[x1][y].setNum(0);
							MainActivity.getMainActivity().addScore(
									cardsMap[x][y].getNum());
							flag = true;
						}
						break;
					}
				}
			}
		}
		if (flag)
		{
			addRandomNum();
			checkComplete();
		}
	}

	private void checkComplete()
	{
		boolean complete = true;
		ALL:
		for (int y = 0; y < 4; y++)
		{
			for (int x = 0; x < 4; x++)
			{
				if (cardsMap[x][y].getNum()==0||
						(x>0&&cardsMap[x][y].equals(cardsMap[x-1][y]))||
						(x<3&&cardsMap[x][y].equals(cardsMap[x+1][y]))||
						(y>0&&cardsMap[x][y].equals(cardsMap[x][y-1]))||
						(y<3&&cardsMap[x][y].equals(cardsMap[x][y+1])))
				{
					complete = false;
					break ALL;
				}
			}
		}
		if (complete)
		{
			new AlertDialog.Builder(getContext()).setTitle("你好").setMessage("游戏结束").setPositiveButton("重新开始", new DialogInterface.OnClickListener()
			{
				
				@Override
				public void onClick(DialogInterface dialog, int which)
				{
					startGame();
				}
			}).show();
		}
	}
}
